﻿using System;
using System.Collections.Generic;
using System.Linq;
using Shell.Common;
using Shell.KnowledgeBase;

namespace Shell.Nodes
{
    public class ResultNode<T> : LeafNode
    {
        public ResultNode(T value)
        {
            Value = value;
        }

        public readonly T Value;
    }
    public class SyntaxExpansionNode : BranchNode
    {
        private readonly Statement _statementToExpand;
        private readonly IEnumerable<SyntaxRule> _rules;
        private readonly Func<Statement, Node> _next;

        public SyntaxExpansionNode(
            Statement statementToExpand,
            IEnumerable<SyntaxRule> rules,
            Func<Statement, Node> next)
        {
            _statementToExpand = statementToExpand;
            _rules = rules;
            _next = next;
        }

        public override IEnumerable<WeightedNode> Process()
        {
            var reduceResult = _rules.SelectMany(rule => Rewriter.Expand(_statementToExpand, rule)).ToArray();

            return Identity(
                reduceResult.Any()
                    ? reduceResult.Select(_ => new SyntaxExpansionNode(_, _rules, _next)).Cast<Node>()
                    : _statementToExpand.Yield().Select(_ => new ResultNode<Statement>(_)));

        }

        public override string ToString()
        {
            return string.Format("Expand: {0}", _statementToExpand);
        }
    }
}